package com.christina.engine.observer;

import lombok.Builder;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 处理事件
 * 表示系统中发生的各种处理事件
 * 
 * @author Christina
 */
@Data
@Builder
public class ProcessingEvent {
    
    /**
     * 事件ID
     */
    private String eventId;
    
    /**
     * 事件类型
     */
    private EventType eventType;
    
    /**
     * 事件源
     */
    private String source;
    
    /**
     * 事件时间
     */
    private LocalDateTime timestamp;
    
    /**
     * 会话ID
     */
    private String sessionId;
    
    /**
     * 用户ID
     */
    private Long userId;
    
    /**
     * 事件数据
     */
    private Map<String, Object> eventData;
    
    /**
     * 事件优先级
     */
    private Priority priority;
    
    /**
     * 事件标签
     */
    private java.util.Set<String> tags;
    
    /**
     * 是否需要持久化
     */
    private Boolean persistent;
    
    /**
     * 事件过期时间
     */
    private LocalDateTime expirationTime;
    
    /**
     * 事件类型枚举
     */
    public enum EventType {
        // 请求处理事件
        REQUEST_RECEIVED,
        REQUEST_VALIDATED,
        REQUEST_PROCESSED,
        REQUEST_COMPLETED,
        REQUEST_FAILED,
        
        // 意图识别事件
        INTENT_RECOGNIZED,
        INTENT_FAILED,
        
        // 上下文事件
        CONTEXT_LOADED,
        CONTEXT_UPDATED,
        CONTEXT_SAVED,
        
        // 决策事件
        DECISION_MADE,
        DECISION_FAILED,
        
        // 路由事件
        ROUTE_SELECTED,
        ROUTE_FAILED,
        
        // 执行事件
        SERVICE_EXECUTION_STARTED,
        SERVICE_EXECUTION_COMPLETED,
        SERVICE_EXECUTION_FAILED,
        
        // 响应事件
        RESPONSE_GENERATED,
        RESPONSE_DECORATED,
        RESPONSE_SENT,
        
        // 状态事件
        STATE_ENTERED,
        STATE_EXITED,
        STATE_TRANSITION,
        STATE_TIMEOUT,
        
        // 系统事件
        SYSTEM_STARTUP,
        SYSTEM_SHUTDOWN,
        HEALTH_CHECK,
        
        // 错误事件
        ERROR_OCCURRED,
        EXCEPTION_THROWN,
        
        // 性能事件
        PERFORMANCE_METRIC,
        RESOURCE_USAGE,
        
        // 用户事件
        USER_LOGIN,
        USER_LOGOUT,
        USER_ACTION,
        
        // 自定义事件
        CUSTOM
    }
    
    /**
     * 事件优先级枚举
     */
    public enum Priority {
        LOW(1),
        NORMAL(2),
        HIGH(3),
        CRITICAL(4);
        
        private final int level;
        
        Priority(int level) {
            this.level = level;
        }
        
        public int getLevel() {
            return level;
        }
    }
    
    /**
     * 创建请求处理事件
     * 
     * @param eventType 事件类型
     * @param source 事件源
     * @param sessionId 会话ID
     * @return 处理事件
     */
    public static ProcessingEvent createRequestEvent(EventType eventType, String source, String sessionId) {
        return ProcessingEvent.builder()
                .eventId(generateEventId())
                .eventType(eventType)
                .source(source)
                .sessionId(sessionId)
                .timestamp(LocalDateTime.now())
                .priority(Priority.NORMAL)
                .persistent(false)
                .build();
    }
    
    /**
     * 创建系统事件
     * 
     * @param eventType 事件类型
     * @param source 事件源
     * @return 处理事件
     */
    public static ProcessingEvent createSystemEvent(EventType eventType, String source) {
        return ProcessingEvent.builder()
                .eventId(generateEventId())
                .eventType(eventType)
                .source(source)
                .timestamp(LocalDateTime.now())
                .priority(Priority.HIGH)
                .persistent(true)
                .build();
    }
    
    /**
     * 创建错误事件
     * 
     * @param source 事件源
     * @param errorMessage 错误信息
     * @param sessionId 会话ID
     * @return 处理事件
     */
    public static ProcessingEvent createErrorEvent(String source, String errorMessage, String sessionId) {
        return ProcessingEvent.builder()
                .eventId(generateEventId())
                .eventType(EventType.ERROR_OCCURRED)
                .source(source)
                .sessionId(sessionId)
                .timestamp(LocalDateTime.now())
                .priority(Priority.HIGH)
                .persistent(true)
                .eventData(Map.of("errorMessage", errorMessage))
                .build();
    }
    
    /**
     * 创建性能事件
     * 
     * @param source 事件源
     * @param metricName 指标名称
     * @param metricValue 指标值
     * @return 处理事件
     */
    public static ProcessingEvent createPerformanceEvent(String source, String metricName, Object metricValue) {
        return ProcessingEvent.builder()
                .eventId(generateEventId())
                .eventType(EventType.PERFORMANCE_METRIC)
                .source(source)
                .timestamp(LocalDateTime.now())
                .priority(Priority.LOW)
                .persistent(false)
                .eventData(Map.of(
                        "metricName", metricName,
                        "metricValue", metricValue
                ))
                .build();
    }
    
    /**
     * 添加事件数据
     * 
     * @param key 数据键
     * @param value 数据值
     * @return 当前事件实例
     */
    public ProcessingEvent addEventData(String key, Object value) {
        if (eventData == null) {
            eventData = new java.util.HashMap<>();
        }
        eventData.put(key, value);
        return this;
    }
    
    /**
     * 添加标签
     * 
     * @param tag 标签
     * @return 当前事件实例
     */
    public ProcessingEvent addTag(String tag) {
        if (tags == null) {
            tags = new java.util.HashSet<>();
        }
        tags.add(tag);
        return this;
    }
    
    /**
     * 检查是否包含指定标签
     * 
     * @param tag 标签
     * @return 是否包含
     */
    public boolean hasTag(String tag) {
        return tags != null && tags.contains(tag);
    }
    
    /**
     * 检查事件是否已过期
     * 
     * @return 是否已过期
     */
    public boolean isExpired() {
        return expirationTime != null && LocalDateTime.now().isAfter(expirationTime);
    }
    
    /**
     * 检查是否为高优先级事件
     * 
     * @return 是否为高优先级
     */
    public boolean isHighPriority() {
        return priority == Priority.HIGH || priority == Priority.CRITICAL;
    }
    
    /**
     * 检查是否为关键事件
     * 
     * @return 是否为关键事件
     */
    public boolean isCritical() {
        return priority == Priority.CRITICAL;
    }
    
    /**
     * 生成事件ID
     * 
     * @return 事件ID
     */
    private static String generateEventId() {
        return "event_" + System.currentTimeMillis() + "_" + 
               (int) (Math.random() * 1000);
    }
    
    @Override
    public String toString() {
        return String.format("ProcessingEvent{id='%s', type=%s, source='%s', timestamp=%s}", 
                eventId, eventType, source, timestamp);
    }
}